// Written by KhanhHH
// 21-09-2012
#include "mobile_service.hpp"
#include "iostream"
#include <boost/thread.hpp>

using namespace boost;
namespace http{
namespace server3 {
int mobile_service::service_count = 0;
mobile_service::mobile_service(string ip_, int port_)
    :ip(ip_),
      port(port_)
{
    service_count++;
    id_service = service_count;
    socket_ptr_.reset(new apache::thrift::transport::TSocket(ip, port));
    transport_ptr_.reset(new apache::thrift::transport::TBufferedTransport(socket_ptr_));
    protocol_ptr_.reset(new apache::thrift::protocol::TBinaryProtocol(transport_ptr_));
    client_ptr_.reset(new UserAgentParserClient(protocol_ptr_));
}
mobile_service::~mobile_service()
{
    try{
          transport_ptr_->close();
          socket_ptr_->close();
    } catch (apache::thrift::TException &tx) {
          std::cout << "ERROR close transport:" << tx.what()<<std::endl;
    }
}

bool mobile_service::init()
{
    try{
        transport_ptr_->open();
        return true;
    }catch(apache::thrift::transport::TTransportException &tx){
       std::cout << "ERROR: Initialization mobile_service is not successful:" << tx.what()<<std::endl;
       return false;
    }
}
void mobile_service::set_cache(boost::shared_ptr<lru_cache> cache_ptr_)
{
    cache_ptr = cache_ptr_;
}

bool  mobile_service::parse_user_agent_service(string& input, string& output)
{
      if(transport_ptr_->isOpen()){
          try {
          //std::cout <<"Asking service"<<std::endl;
          //std::string input_str_="Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16";
          //std::string result_str;
          //std::cout<<"Calling service from thread "<<boost::this_thread::get_id()<<std::endl;
          client_ptr_->parse(output,input);
          //std::cout <<"\tresult: "<<output<<std::endl;
          } catch (apache::thrift::TException &tx) {
            std::cout << "ERROR parsing:" << tx.what()<<std::endl;
            return false;
          }
      }else{
          //if not open --> try open again
          try{
                transport_ptr_->open();
                client_ptr_->parse(output,input);
          }catch(apache::thrift::TException &tx){
                std::cout << "ERROR open Transport:" << tx.what()<<std::endl;
                return false;
          }
      }

    return true;
}

//this function will be called from Lua for parsing user agent
bool mobile_service::parse_user_agent(string &input, string &output)
{
    // call caching ojbect for getting parsed string
    if(!(*cache_ptr.get())(input,output))
    {
        //Asking mobile service for the new record and then update with caching
        if(parse_user_agent_service(input,output)){
            __sync_fetch_and_add(&server::cache_miss,1);
            cache_ptr->insert(input,output);
            return true;
        }
        else
        {
            return false;
        }
    }else{
        //Get cached data
         __sync_fetch_and_add(&server::cache_hit,1);
         return true;
    }

}

}
}
